#include "asio_AsyncConnector.h"
#include "asio_NetworkHandler.h"
#include "asio_NetworkPacket.h"
#include "ClientHandler.h"
#include "bufstream.h"

namespace XGC
{
	namespace net
	{
		asio_AsyncConnector::asio_AsyncConnector( io_service &service )
			: service_(service)
		{
		}

		asio_AsyncConnector::~asio_AsyncConnector(void)
		{
		}

		bool asio_AsyncConnector::Connect( const char* pszAddress, short port, IMessageQueue* pMessageQueue, _uint32 nTimeout )
		{
			system::error_code ec;
			ip::address_v4 addr( ip::address_v4::from_string( pszAddress, ec ) );
			if( ec )
				return false;

			asio_NetworkHandlerPtr pHandler( new asio_NetworkHandler( service_, new CClientHandler( pMessageQueue ) ) );
			pHandler->socket().async_connect( 
				ip::tcp::endpoint( addr, port ), 
				boost::bind(&asio_AsyncConnector::handle_connect, this, pHandler, pMessageQueue, asio::placeholders::error )
				);

			thread t(boost::bind(&asio::io_service::run, &service_));
			return true;
		}

		void asio_AsyncConnector::handle_connect( asio_NetworkHandlerPtr pHandler, IMessageQueue* pMessageQueue, const system::error_code& error )
		{
			if (!error)
			{
				pHandler->accpet();
			}
			else
			{
				pHandler->socket().close();
				if( pMessageQueue )
				try
				{
					asio_NetworkPacket* pPacket = new asio_NetworkPacket( -1, NULL );
					bufstream in( pPacket->data(), pPacket->capacity() );
					in
						<< _byte(SYSTEM_MESSAGE_TYPE)
						<< _byte(EVENT_ERROR)
						;
					pPacket->offset( asio_NetworkPacket::write, in.wd() );
					pMessageQueue->PushMessage( pPacket );
				}
				catch( asio_NetworkPacket* pPacket )
				{
					pPacket->release();
				}
				catch( std::exception exp )
				{
				}
			}
			delete this;
		}
	}
}